package com.gs.synedocket.fragment.driver;

import android.Manifest;
import android.content.Intent;
import android.widget.CompoundButton;
import android.widget.RadioButton;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.gs.synedocket.R;
import com.gs.synedocket.apiresult.ApiResultData;
import com.gs.synedocket.constant.AllConstants;
import com.gs.synedocket.constant.EventCode;
import com.gs.synedocket.db.bean.Event;
import com.gs.synedocket.db.dao.LogUtil;
import com.gs.synedocket.db.dto.DriverSignDto;
import com.gs.synedocket.db.sqlite.DBApi;
import com.gs.synedocket.dialog.CompleteWindow;
import com.gs.synedocket.dialog.DialogUtil;
import com.gs.synedocket.dialog.LoadingDialogUtils;
import com.gs.synedocket.dialog.SureDialog;
import com.gs.synedocket.dialog.ToastDialogUtil;
import com.gs.synedocket.dialog.ToastDialogUtils;
import com.gs.synedocket.fragment.base.BaseFragment;
import com.gs.synedocket.presenter.DriverPresenter;
import com.gs.synedocket.service.GpsService;
import com.gs.synedocket.util.AppUtil;
import com.gs.synedocket.util.DateUtil;
import com.gs.synedocket.util.DensityUtil;
import com.gs.synedocket.util.DocketUtil;
import com.gs.synedocket.util.PermissionUtil;
import com.gs.synedocket.util.ToastUtil;
import com.gs.synedocket.view.IDriverView;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.Date;

public class DriverFragment extends BaseFragment<IDriverView, DriverPresenter> implements IDriverView {

    private RadioButton rbArriveSite, rbStart, rbComplete, rbLeave, rbArrivePlant, rbSelect;
    private CompleteWindow completeWindow;
    private SureDialog sureDialog;
    private DriverPlantFragment fragment;
    private int newState, colorBlack, color333;
    private DriverSignDto mBean;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_driver;
    }

    @Override
    protected DriverPresenter createPresenter() {
        return new DriverPresenter();
    }

    @Override
    protected void initView() {
        EventBus.getDefault().register(this);
        PermissionUtil.addPermission(getActivity(), new String[]{
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.ACCESS_WIFI_STATE,
                Manifest.permission.CHANGE_NETWORK_STATE}, AllConstants.GPS_LOCATION);
        colorBlack = getResources().getColor(R.color.black);
        color333 = getResources().getColor(R.color.color_333);
        rbArriveSite = fd(R.id.rb_arrive_site);
        rbStart = fd(R.id.rb_start);
        rbComplete = fd(R.id.rb_complete);
        rbLeave = fd(R.id.rb_leave_site);
        rbArrivePlant = fd(R.id.rb_arrive_plant);
        MyRBOnCheckedChangeListener myRBOnCheckedChangeListener = new MyRBOnCheckedChangeListener();
        rbStart.setOnCheckedChangeListener(myRBOnCheckedChangeListener);
        rbArriveSite.setOnCheckedChangeListener(myRBOnCheckedChangeListener);
        rbComplete.setOnCheckedChangeListener(myRBOnCheckedChangeListener);
        rbLeave.setOnCheckedChangeListener(myRBOnCheckedChangeListener);
        rbArrivePlant.setOnCheckedChangeListener(myRBOnCheckedChangeListener);
        fragment = new DriverPlantFragment();
        showFragment();
    }

    @Override
    protected void initData() {
        if (DocketUtil.getInstance().isLogDetail()) {
            setLogDetailView();
            return;
        }
        mBean = null;
        review();
    }

    private void review() {
        setDocketView();
        Integer oldState = DocketUtil.getInstance().getTruckState();
        if (oldState == null) {
            return;
        }
//        if (oldState == 5) { // 已Arrive Plane
//            setAllUnEnable();
//        } else
        if (oldState == 4) { // 已Leave Site
            setArriveSiteUnEnable();
            setStartUnEnable();
            setCompleteUnEnable();
            setLeaveUnEnable();
        } else if (oldState == 3) {// 已Complete Discharge,不一定OK/Additional Charge
            setArriveSiteUnEnable();
            setStartUnEnable();
            Integer driverState = DocketUtil.getInstance().getDriverState();
            if (driverState != null) {
                if (driverState == 2 || driverState == 3 || driverState == 4 || driverState == 5) {// 已OK/Additional Charge/Without Sign
                    setCompleteUnEnable();
                }
            }
        } else if (oldState == 2) {// 已Start Discharge
            setArriveSiteUnEnable();
            setStartUnEnable();
        } else if (oldState == 1) {// 已Arrive Site,不一定QC Check
            Integer qcState = DocketUtil.getInstance().getQcState();
            if (qcState != null) {
                switch (qcState) {
                    case 0:// QC Check Fail
                        setArriveSiteUnEnable();
                        setStartUnEnable();
                        setCompleteUnEnable();
                        break;
                    case 1:// QC Check Pass
                        setArriveSiteUnEnable();
                        break;
                }
            }
        }
    }

    private void setPlantUnEnable() {
//        DensityUtil.setNewHeight(rbArrivePlant, DensityUtil.dp2px(64));
        setUnEnable(rbArrivePlant, R.string.arrive_plant3, DocketUtil.getInstance().getArrivePlantAt(), DocketUtil.getInstance().getArrivePlantGps());
    }

    private void setLeaveUnEnable() {
//        DensityUtil.setNewHeight(rbLeave, DensityUtil.dp2px(64));
        setUnEnable(rbLeave, R.string.leave_site3, DocketUtil.getInstance().getLeaveSiteAt(), DocketUtil.getInstance().getLeaveSiteGps());
    }

    private void setCompleteUnEnable() {
//        DensityUtil.setNewHeight(rbComplete, DensityUtil.dp2px(64));
        setUnEnable(rbComplete, R.string.complete_discharge3, DocketUtil.getInstance().getEndDisAt(), DocketUtil.getInstance().getEndDisGps());
    }

    private void setStartUnEnable() {
//        DensityUtil.setNewHeight(rbStart, DensityUtil.dp2px(64));
        setUnEnable(rbStart, R.string.start_discharge3, DocketUtil.getInstance().getStartDisAt(), DocketUtil.getInstance().getStartDisGps());
    }

    private void setArriveSiteUnEnable() {
//        DensityUtil.setNewHeight(rbArriveSite, DensityUtil.dp2px(64));
        setUnEnable(rbArriveSite, R.string.arrive_site3, DocketUtil.getInstance().getArriveSiteAt(), DocketUtil.getInstance().getArriveSiteGps());
    }

    private void setDocketView() {
        if (rbArriveSite.getHeight() > DensityUtil.dp2px(44)) {
            DensityUtil.setNewHeight(rbArriveSite, DensityUtil.dp2px(44));
            DensityUtil.setNewHeight(rbStart, DensityUtil.dp2px(44));
            DensityUtil.setNewHeight(rbComplete, DensityUtil.dp2px(44));
            DensityUtil.setNewHeight(rbLeave, DensityUtil.dp2px(44));
            DensityUtil.setNewHeight(rbArrivePlant, DensityUtil.dp2px(44));
        }
        rbArriveSite.setText(R.string.arrive_site);
        rbStart.setText(R.string.start_discharge);
        rbComplete.setText(R.string.complete_discharge);
        rbLeave.setText(R.string.leave_site);
        rbArrivePlant.setText(R.string.arrive_plant);
        setEnable(rbArriveSite);
        setEnable(rbStart);
        setEnable(rbComplete);
        setEnable(rbLeave);
        setEnable(rbArrivePlant);
    }

    private void setLogDetailView() {
        setAllUnEnable();
        DensityUtil.setNewHeight(rbArriveSite, DensityUtil.dp2px(64));
        DensityUtil.setNewHeight(rbStart, DensityUtil.dp2px(64));
        DensityUtil.setNewHeight(rbComplete, DensityUtil.dp2px(64));
        DensityUtil.setNewHeight(rbLeave, DensityUtil.dp2px(64));
        DensityUtil.setNewHeight(rbArrivePlant, DensityUtil.dp2px(64));
        Date arriveSiteAt = DocketUtil.getInstance().getArriveSiteAt();
        rbArriveSite.setText(getString(R.string.arrive_site2, DateUtil.DateTime2Str(arriveSiteAt), DocketUtil.getInstance().getArriveSiteGps()));
        Date startDisAt = DocketUtil.getInstance().getStartDisAt();
        rbStart.setText(getString(R.string.start_discharge2, DateUtil.DateTime2Str(startDisAt), DocketUtil.getInstance().getStartDisGps()));
        Date endDisAt = DocketUtil.getInstance().getEndDisAt();
        rbComplete.setText(getString(R.string.complete_discharge1, DateUtil.DateTime2Str(endDisAt), DocketUtil.getInstance().getEndDisGps()));
        Date leaveSiteAt = DocketUtil.getInstance().getLeaveSiteAt();
        rbLeave.setText(getString(R.string.leave_site1, DateUtil.DateTime2Str(leaveSiteAt), DocketUtil.getInstance().getLeaveSiteGps()));
        Date arrivePlantAt = DocketUtil.getInstance().getArrivePlantAt();
        rbArrivePlant.setText(getString(R.string.arrive_plant1, DateUtil.DateTime2Str(arrivePlantAt), DocketUtil.getInstance().getArrivePlantGps()));
    }

    private void setAllUnEnable() {
        setUnEnable(rbArriveSite);
        setUnEnable(rbStart);
        setUnEnable(rbComplete);
        setUnEnable(rbLeave);
        setUnEnable(rbArrivePlant);
    }

    @Override
    public void onUpdateSuccess(ApiResultData<String> apiResultData) {
        if (apiResultData.getStatus() != 2000) {
            mBean = null;
            rbArriveSite.setChecked(false);
            rbStart.setChecked(false);
            rbComplete.setChecked(false);
            ToastDialogUtils.getInstance().showInfoMessage(context, apiResultData.getMessage());
            return;
        }
        insertLog(rbSelect.getText().toString());
        rbSelect = null;
        DocketUtil.getInstance().setTruckState(newState);
        handle(apiResultData.getMessage());
    }

    private void handle(String message) {
        Date date = mBean.getSignAt();
        String gps = mBean.getGps();
        String time = DateUtil.DateTimeToStr(date, "HH:mm");
        Integer truckState = mBean.getState();
        DBApi.getInstance().updateDocketSign(mBean.getDocketId(), truckState == 1 ? 1 : DocketUtil.getInstance().getDriverState(),
                truckState, date, gps, mBean.getGpsLoc());
        mBean = null;
        switch (newState) {
            // Arrive Site
            case 1:
                DocketUtil.getInstance().setArriveSiteAt(date);
                DocketUtil.getInstance().setArriveSiteGps(gps);
                DocketUtil.getInstance().setDriverState(1);
                rbArriveSite.setChecked(false);
                qcCheck();
                break;
            // Start Discharge
            case 2:
                DocketUtil.getInstance().setStartDisAt(date);
                DocketUtil.getInstance().setStartDisGps(gps);
                ToastDialogUtil.getInstance().makeText(context, context.getString(R.string.start_discharge_at, time));
                setStartUnEnable();
                break;
            // Complete Discharge
            case 3:
                DocketUtil.getInstance().setEndDisAt(date);
                DocketUtil.getInstance().setEndDisGps(gps);
                ToastDialogUtil.getInstance().makeText(context, context.getString(R.string.complete_discharge_at, time));
                showPopup();
                break;
            // Leave Site
            case 4:
                DocketUtil.getInstance().setLeaveSiteAt(date);
                DocketUtil.getInstance().setLeaveSiteGps(gps);
                ToastUtil.showToast(message);
                setLeaveUnEnable();
                break;
            // Arrive Plant
            case 5:
                DocketUtil.getInstance().setArrivePlantAt(date);
                DocketUtil.getInstance().setArrivePlantGps(gps);
                setPlantUnEnable();
                DocketUtil.getInstance().setDocketId("");
                ToastUtil.showToast(message);
                ToastUtil.showToast(R.string.get_new_docket);
                EventBus.getDefault().post(new Event(EventCode.EVENT_ARRIVE_PLANT));
                break;
        }
    }

    /**
     * 保存log
     */
    private void insertLog(String string) {
        LogUtil.getInstance().insertOrReplaceData(DocketUtil.getInstance().getDocketNo() + "-" + string + "成功");
    }

    @Override
    public void onUpdateFails(Exception e) {
        ToastDialogUtils.getInstance().showInfoMessage(context, R.string.network_error);
        rbStart.setChecked(false);
        rbComplete.setChecked(false);
        rbArriveSite.setChecked(false);
        newState = DocketUtil.getInstance().getTruckState();
        mBean = null;
    }

    @Override
    public void showLoading() {
        LoadingDialogUtils.getInstance().showLoading(context);
    }

    @Override
    public void hideLoading() {
        LoadingDialogUtils.getInstance().dismiss();
    }

    class MyRBOnCheckedChangeListener implements CompoundButton.OnCheckedChangeListener {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            Integer oldState = DocketUtil.getInstance().getTruckState();
            int checkId = buttonView.getId();
            if (isChecked) {
                if (DocketUtil.getInstance().getUpgradeLevel() == AllConstants.UPGRADE_FIRST) {
                    ToastUtil.showToast(R.string.upgrade_first);
                    LogUtil.getInstance().insertOrReplaceData(getString(R.string.upgrade_log, AppUtil.getInstance().getVersion()));
                    return;
                }
                if (oldState == null) {
                    ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_confirm_docket);
                    buttonView.setChecked(false);
                    return;
                }
                rbSelect = (RadioButton) buttonView;
                Integer qcState = DocketUtil.getInstance().getQcState();
                if (checkId == R.id.rb_arrive_site) {
                    if (oldState == 1) {
                        qcCheck();
                        rbArriveSite.setChecked(false);
                        return;
                    }
                    newState = 1;
                    showSureDialog(R.string.arrive_site, rbArriveSite);
                } else if (checkId == R.id.rb_start) {
                    if (oldState < 1) {
                        ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_arrive_site);
                        rbStart.setChecked(false);
                        return;
                    }
                    if (qcState == null || qcState == -1) {
                        qcCheck();
                        rbStart.setChecked(false);
                        return;
                    }
                    newState = 2;
                    showSureDialog(R.string.start_discharge, rbStart);
                } else if (checkId == R.id.rb_complete) {
                    if (oldState < 2) {
                        ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_start_discharge);
                        rbComplete.setChecked(false);
                        return;
                    }
                    if (oldState == 3) {
                        showPopup();
                        return;
                    }
                    newState = 3;
                    showSureDialog(R.string.complete_discharge, rbComplete);
                } else if (checkId == R.id.rb_leave_site) {
                    if (qcState != 0) {
                        if (oldState < 3) {
                            ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_complete_discharge);
                            rbLeave.setChecked(false);
                            return;
                        }
                        Integer driverState = DocketUtil.getInstance().getDriverState();
                        if (driverState == null || driverState == 1) {
                            ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_sign_complete);
                            showPopup();
                            rbLeave.setChecked(false);
                            return;
                        }
                    }
                    newState = 4;
                    showSureDialog(R.string.leave_site, rbLeave);
                } else if (checkId == R.id.rb_arrive_plant) {
                    if (oldState < 4) {
                        ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_leave_site);
                        rbArrivePlant.setChecked(false);
                        return;
                    }
                    newState = 5;
                    showSureDialog(R.string.arrive_plant, rbArrivePlant);
                }
            }
        }
    }

    private void showPopup() {
        if (completeWindow == null) {
            completeWindow = new CompleteWindow(context, new CompleteWindow.IDoneListener() {
                @Override
                public void additionalFromDialog() {
                    EventBus.getDefault().post(new Event(EventCode.EVENT_ADDITIONAL));
                }

                @Override
                public void okFromDialog() {
                    EventBus.getDefault().post(new Event(EventCode.EVENT_OK));
                }
            });
            completeWindow.setOnDismissListener(() -> {
                rbComplete.setChecked(false);
                if (rbLeave.isChecked()) {
                    rbLeave.setChecked(false);
                }
            });
        }
        completeWindow.showAsDropDown(rbComplete, 0, DensityUtil.dp2px(20));
    }

    private void qcCheck() {
        ToastUtil.showToast(R.string.p_qc_check);
        EventBus.getDefault().post(new Event(EventCode.EVENT_ARRIVE_SITE));
    }

    private void showSureDialog(int title, RadioButton rb) {
        sureDialog = new SureDialog(context, title, this::update);
        sureDialog.setOnDismissListener(dialog -> {
            sureDialog = null;
            if (rb == rbComplete && DocketUtil.getInstance().getTruckState() == 3) {
                return;
            }
            rb.setChecked(false);
        });
        sureDialog.show();
    }

    private void update() {
        mBean = new DriverSignDto();
        mBean.setDocketId(DocketUtil.getInstance().getDocketId());
        mBean.setState(newState);
        mBean.setSignAt(new Date());
        mBean.setGps(GpsService.getGps());
        mBean.setGpsLoc(GpsService.getGpsLoc());
        mPresenter.update(mBean);
    }

    private void showFragment() {
        FragmentManager fm = getChildFragmentManager();
        FragmentTransaction transaction = fm.beginTransaction();
        if (fragment.isAdded()) {
            transaction.show(fragment);
        } else {
            transaction.add(R.id.fl_content, fragment);
        }
        transaction.commit();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        fragment.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(Event event) {
        int what = event.getWhat();
        switch (what) {
            // 完成QC Check
            case EventCode.EVENT_DONE_QC_CHECK:
                setUnEnable(rbArriveSite);
                if (event.getState()) {
                    ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_start_discharge);
                } else {
                    ToastDialogUtils.getInstance().showInfoMessage(context, R.string.p_leave_site);
                    setUnEnable(rbStart);
                    setUnEnable(rbComplete);
                }
                break;
            // 完成落貨
            case EventCode.EVENT_DONE_COMPLETE:
                setCompleteUnEnable();
                break;
            case EventCode.EVENT_DONE_REVERT_SIGN:
                if (isVisible()) {
                    review();
                }
                break;
        }
    }

    private void setEnable(RadioButton rb) {
        rb.setTextColor(colorBlack);
        rb.setEnabled(true);
        rb.setBackgroundResource(R.drawable.driver_rb_selector);
    }

    private void setUnEnable(RadioButton rb) {
        rb.setTextColor(color333);
        rb.setEnabled(false);
        rb.setBackgroundResource(R.drawable.driver_rb_unenable);
    }

    private void setUnEnable(RadioButton rb, int textRes, Date date, String gps) {
        rb.setTextColor(color333);
        rb.setEnabled(false);
        rb.setText(getString(textRes, DateUtil.DateTime2Str(date)));
        rb.setBackgroundResource(R.drawable.driver_rb_unenable);
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            initData();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        DialogUtil.getInstance().dialogDestroy(completeWindow);
        DialogUtil.getInstance().dialogDestroy(sureDialog);
    }
}
